package com.ruoyi.web.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.web.config.WxPayConfig;
import com.ruoyi.web.service.WeChatPayService;
import com.ruoyi.web.util.OrderNoUtils;
import com.ruoyi.web.util.WXPayUtil;
import com.ruoyi.web.vo.WXPayOrderReqVO;
import com.ruoyi.web.vo.WxPayRespVO;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/*
 *  @author 雨安
 *  类名： WxChatPayServiceImpl
 *  创建时间：2025/2/19
 */
@Service
@Slf4j
public class WxChatPayServiceImpl implements WeChatPayService {

    @Resource
    private WxPayConfig wxPayConfig;

    //获取预支付
    @Override
    public WxPayRespVO createOrder(WXPayOrderReqVO req) throws Exception {
        try {
            // 使用自动更新平台证书的RSA配置
            // 一个商户号只能初始化一个配置，否则会因为重复的下载任务报错
            Config config =
                    new RSAAutoCertificateConfig.Builder()
                            .merchantId(wxPayConfig.getMchId())
                            .privateKeyFromPath(wxPayConfig.getPrivateKeyPath())
                            .merchantSerialNumber(wxPayConfig.getMchSerialNo())
                            .apiV3Key(wxPayConfig.getApiV3Key())
                            .build();
            // 构建service
            JsapiService service = new JsapiService.Builder().config(config).build();
            // request.setXxx(val)设置所需参数，具体参数可见Request定义
            PrepayRequest request = new PrepayRequest();
            //金额
            Amount amount = new Amount();
            //设置金额
            amount.setTotal(req.getTotalPrice().intValue());
//            amount.setTotal(1);
            //设置金额
            request.setAmount(amount);
            //设置金额
            request.setAppid(wxPayConfig.getAppid());
            //设置商户号
            request.setMchid(wxPayConfig.getMchId());
            //设置商品名称
            request.setDescription(req.getGoodsName());
            //设置回调地址
            request.setNotifyUrl(wxPayConfig.getNotifyDomain() + "/uni/pay/success");
            //设置订单号
            request.setOutTradeNo(req.getOrderSn().toString());
            //设置类型
            request.setAttach(req.getOrderType());
            //创建pay对象
            Payer payer = new Payer();
            //设置用户openid
            payer.setOpenid(req.getOpenId());
            //设置pay对象
            request.setPayer(payer);
            // 调用下单方法，得到应答
            PrepayResponse response = service.prepay(request);
            //创建vo对象
            WxPayRespVO vo = new WxPayRespVO();
            //得到事件戳
            Long timeStamp = System.currentTimeMillis() / 1000;
            //设置事件戳
            vo.setTimeStamp(timeStamp);
            //设置字符串
            String substring = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
            //设置字符串
            vo.setNonceStr(substring);
            //拼接
            String signatureStr = Stream.of(wxPayConfig.getAppid(), String.valueOf(timeStamp), substring, "prepay_id=" + response.getPrepayId())
                    .collect(Collectors.joining("\n", "", "\n"));
            //得到签名
            String sign = WXPayUtil.getSign(signatureStr, wxPayConfig.getPrivateKeyPath());
            //设置签名
            vo.setPaySign(sign);
            //设置请求支付id
            vo.setPrepayId("prepay_id=" + response.getPrepayId());
            //返回vo对象
            return vo;
        }catch (ServiceException e){
            JSONObject parse = JSONObject.parseObject(e.getResponseBody());
            throw new RuntimeException(e.getMessage());
        }catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }
    }

    @Override
    public WxPayRespVO createMemberOrder(WXPayOrderReqVO req) throws Exception {
        try {
            // 使用自动更新平台证书的RSA配置
            // 一个商户号只能初始化一个配置，否则会因为重复的下载任务报错
            Config config =
                    new RSAAutoCertificateConfig.Builder()
                            .merchantId(wxPayConfig.getMchId())
                            .privateKeyFromPath(wxPayConfig.getPrivateKeyPath())
                            .merchantSerialNumber(wxPayConfig.getMchSerialNo())
                            .apiV3Key(wxPayConfig.getApiV3Key())
                            .build();
            // 构建service
            JsapiService service = new JsapiService.Builder().config(config).build();
            // request.setXxx(val)设置所需参数，具体参数可见Request定义
            PrepayRequest request = new PrepayRequest();
            //金额
            Amount amount = new Amount();
            //设置金额
            amount.setTotal(req.getTotalPrice().intValue());
            //此金额用于测试
//            amount.setTotal(1);
            //设置金额
            request.setAmount(amount);
            //设置金额
            request.setAppid(wxPayConfig.getAppid());
            //设置商户号
            request.setMchid(wxPayConfig.getMchId());
            //设置商品名称
            request.setDescription(req.getGoodsName());
            //设置回调地址
            request.setNotifyUrl(wxPayConfig.getNotifyDomain() + "/uni/pay/pay/success");
            //设置订单号
            request.setOutTradeNo(req.getOrderSn().toString());
            //设置类型
            request.setAttach(req.getOrderType());
            //创建pay对象
            Payer payer = new Payer();
            //设置用户openid
            payer.setOpenid(req.getOpenId());
            //设置pay对象
            request.setPayer(payer);
            // 调用下单方法，得到应答
            PrepayResponse response = service.prepay(request);
            //创建vo对象
            WxPayRespVO vo = new WxPayRespVO();
            //得到事件戳
            Long timeStamp = System.currentTimeMillis() / 1000;
            //设置事件戳
            vo.setTimeStamp(timeStamp);
            //设置字符串
            String substring = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
            //设置字符串
            vo.setNonceStr(substring);
            //拼接
            String signatureStr = Stream.of(wxPayConfig.getAppid(), String.valueOf(timeStamp), substring, "prepay_id=" + response.getPrepayId())
                    .collect(Collectors.joining("\n", "", "\n"));
            //得到签名
            String sign = WXPayUtil.getSign(signatureStr, wxPayConfig.getPrivateKeyPath());
            //设置签名
            vo.setPaySign(sign);
            //设置请求支付id
            vo.setPrepayId("prepay_id=" + response.getPrepayId());
            //返回vo对象
            return vo;
        }catch (ServiceException e){
            JSONObject parse = JSONObject.parseObject(e.getResponseBody());
            throw new RuntimeException(e.getMessage());
        }catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }
    }


}
